package com.hontlong.toy.parrot;

import org.apache.log4j.Logger;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.sql.ResultSet;

/**
 * <b>鹦鹉，学舌的人</b><br>
 * 分析学习抓取来的网页，并存储到数据库
 * 
 * @author zhaigy
 * @date Feb 14, 2008
 */
public class Parrot {
	static class AskWriter {
		private void close() {
		}

		void write(final Ask ask) {
			Connection conn = null;
			try {
				conn = DBConnectFactory.getDBConnection("boy");
				final Statement stat = conn
						.createStatement(ResultSet.TYPE_FORWARD_ONLY,
								ResultSet.CONCUR_UPDATABLE);
				final ResultSet rs = stat
						.executeQuery("select 1 from t_ask where id="
								+ ask.getId());
				// 如果先前有的话，先删除
				if (rs.next()) {
					// 有记录
					if (stat.executeUpdate("delete from t_ask where id="
							+ ask.getId()) <= 0) {
						return;// error
					}
					stat.executeUpdate("delete from t_answer where askId="
							+ ask.getId());
				}
				rs.close();

				final PreparedStatement ps = conn
						.prepareStatement(
								"insert into t_ask(id,askTitle,ask,`type`) values(?,?,?,?)",
								ResultSet.TYPE_FORWARD_ONLY,
								ResultSet.CONCUR_UPDATABLE);
				ps.setInt(1, ask.getId());
				ps.setString(2, ask.getAskTitle());
				ps.setString(3, ask.getAsk());
				ps.setString(4, ask.getType());
				if (ps.executeUpdate() > 0) {
					final PreparedStatement ps2 = conn
							.prepareStatement(
									"insert into t_answer(id,askid,answer,score)values(null,?,?,?)",
									ResultSet.TYPE_FORWARD_ONLY,
									ResultSet.CONCUR_UPDATABLE);
					for (final String answer : ask.getAnswers()) {
						ps2.setInt(1, ask.getId());
						ps2.setString(2, answer);
						ps2.setInt(3, 0);
						ps2.executeUpdate();
					}
				}
			} catch (final SQLException e) {
				e.printStackTrace();
			}
			// System.out.println(ask.toString());
			try {
				conn.close();
			} catch (final SQLException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(Parrot.class);

	/**
	 * @param args
	 */
	public static void main(final String[] args) {
		if (Parrot.logger.isDebugEnabled()) {
			Parrot.logger.debug("main(String[]) - start");
		}

		final String setting = "./parrot.setting.properties";
		final Properties prop = new Properties();
		try {
			prop.load(new FileInputStream(setting));
		} catch (final FileNotFoundException e) {
			Parrot.logger.error("main(String[])", e);
		} catch (final IOException e) {
			Parrot.logger.error("main(String[])", e);
		}

		final String curIdFile = prop.getProperty("curIdFile",
				"./parrot.curId.txt");
		final int maxId = Integer.parseInt(prop.getProperty("maxId"));
		final RandomAccessFile idFile = new Object() {
			public RandomAccessFile cal() {
				if (Parrot.logger.isDebugEnabled()) {
					Parrot.logger.debug("cal() - start");
				}

				try {
					final File f = new File(curIdFile);
					RandomAccessFile idFile = null;
					if (!f.exists()) {
						idFile = new RandomAccessFile(curIdFile, "rwd");
						idFile.writeBytes("" + (0));
					} else {
						idFile = new RandomAccessFile(curIdFile, "rwd");
					}

					if (Parrot.logger.isDebugEnabled()) {
						Parrot.logger.debug("cal() - end");
					}
					return idFile;
				} catch (FileNotFoundException e) {
					Parrot.logger.error("cal()", e);

					throw new RuntimeException();
				} catch (IOException e) {
					Parrot.logger.error("cal()", e);

					throw new RuntimeException();
				}
			}
		}.cal();

		final int curId = new Object() {
			public int cal() {
				if (Parrot.logger.isDebugEnabled()) {
					Parrot.logger.debug("cal() - start");
				}

				try {
					idFile.seek(0);
					String line = idFile.readLine();
					int returnint = Integer.parseInt(line);
					if (Parrot.logger.isDebugEnabled()) {
						Parrot.logger.debug("cal() - end");
					}
					return returnint;
				} catch (IOException e) {
					Parrot.logger.error("cal()", e);

					throw new RuntimeException();
				}
			}
		}.cal();

		final String downDir = prop.getProperty("downDir");
		{
			final File file = new File(downDir);
			if (!file.exists() || !file.isDirectory()) {
				throw new RuntimeException();
			}
		}

		// 读取文件
		final Parser parser = new ZhiDaoParser();
		final AskWriter writer = new AskWriter();
		int num = 0;
		for (int id = curId + 1; id < maxId; ++id) {
			final int subDirNum = ((id - 1) / 1000) + 1;
			final String ofName = downDir + subDirNum + "/" + id + ".html";
			try {
				final Reader reader = new BufferedReader(new FileReader(ofName));
				final StringBuilder sb = new StringBuilder();
				for (int c; (c = reader.read()) >= 0;) {
					sb.append((char) c);
				}
				final Ask ask = parser.parser(sb.toString());
				if (ask != null) {
					ask.setId(id);
					writer.write(ask);
				}
			} catch (final FileNotFoundException e) {
				Parrot.logger.error("main(String[])", e);
			} catch (final IOException e) {
				Parrot.logger.error("main(String[])", e);
			}
			try {
				idFile.seek(0);
				idFile.writeBytes("" + id);
			} catch (final IOException e) {
				Parrot.logger.error("main(String[])", e);
			}
			++num;
			if (num % 100 == 0) {
				Parrot.logger.info("already " + num);
			}
		}
		writer.close();
		Parrot.logger.info("total " + num);
		if (Parrot.logger.isDebugEnabled()) {
			Parrot.logger.debug("main(String[]) - end");
		}
	}
}
